package com.zzyl.service.impl;

import cn.hutool.core.bean.BeanUtil;
import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import com.zzyl.base.PageResponse;
import com.zzyl.dto.ReservationDto;
import com.zzyl.entity.Reservation;
import com.zzyl.mapper.ReservationMapper;
import com.zzyl.service.ReservationService;
import com.zzyl.utils.UserThreadLocal;
import com.zzyl.vo.ReservationCountVo;
import com.zzyl.vo.ReservationVo;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.time.Instant;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.util.ArrayList;
import java.util.List;

@Slf4j
@Service
public class ReservationServiceImpl implements ReservationService {

    @Autowired
    private ReservationMapper reservationMapper;

    /**
     * 查询取消预约数量
     *
     * @return
     */
    @Override
    public Integer FindBycancelled() {
//        获取小程序的用户id
        Long userId = UserThreadLocal.getUserId();
//        生成当天的开始和结束时间
        LocalDateTime begin = LocalDate.now().atStartOfDay();
        LocalDateTime end = LocalDate.now().atTime(23, 59, 59);
//        根据id查询当天的取消预约的数量
        Integer num = reservationMapper.selectBycancelled(userId, begin, end);
        return num;
    }

    /**
     * 新增预约
     *
     * @param dto
     * @return
     */
    @Override
    public void save(ReservationDto dto) {
//        对象属性拷贝
        Reservation reservation = BeanUtil.toBean(dto, Reservation.class);
        reservation.setStatus(0);
        reservationMapper.insert(reservation);
    }

    /**
     * 分页查询预约
     *
     * @param status
     * @param pageNum
     * @param pageSize
     * @return
     */
    @Override
    public PageResponse<ReservationVo> findByPage(Integer status, Integer pageNum, Integer pageSize) {
//        使用pageHelper设置
        PageHelper.startPage(pageNum, pageSize);
//        进行查询
        List<ReservationVo> list = reservationMapper.selectByCondition(status);
//        强转page对象
        Page<ReservationVo> page = (Page<ReservationVo>) list;
        PageResponse<ReservationVo> pageResponse = PageResponse.of(page, ReservationVo.class);
//        返回PageResponse对象
        return pageResponse;
    }

    /**
     * 每个时间段最多预约6次
     *
     * @param time 毫秒值
     * @return
     */
    @Override
    public List<ReservationCountVo> findCountByTime(Long time) {
//        把time转LocalDateTime
        LocalDateTime begin = Instant.ofEpochMilli(time).atZone(ZoneId.of("Asia/Shanghai")).toLocalDateTime().plusHours(8);
        LocalDateTime end = begin.plusHours(18);
//        查询数据库中当天时段的预约次数
        List<ReservationCountVo> voList = reservationMapper.selectByCountByTime(begin, end);
        List<ReservationCountVo> result = new ArrayList<>();
//        把预约时段补全
//        每天从8点开始
        while (begin.isBefore(end) || begin.equals(end)) {
//            每个时间段最多预约6次
            ReservationCountVo vo = new ReservationCountVo(6, begin);
//            如果这个时段已经在数据库存在，就用 6- 数据库的此时，算出剩余的次数
            for (ReservationCountVo countVo : voList) {
                if (countVo.getTime().equals(begin)) {
                    countVo.setCount(6 - countVo.getCount());
                    break;
                }
            }
            result.add(vo);
//            把时间段增加半小时 8:00 -> 8:30
            begin = begin.plusMinutes(30);
        }
        return result;
    }

    /**
     * 每个小时的10分 和 40分 检查预约状态
     * 如果没有完成,就把状态改成过期-3
     */
    @Override
    public void overdue() {
//        获取当前的时间
        LocalDateTime now = LocalDateTime.now();
        reservationMapper.updateStatusOverDue(now);
    }

    /**
     * 取消预约
     * @param id
     * @return
     */
    @Override
    public void update(Long id) {
        reservationMapper.updateStatus(id);
    }
}
